<?php
namespace TwinPeaks\Core\Http;

use TwinPeaks\Core as Core;

class CRequest
{
	use Core\TAppInjector;
	
	/**
	 * @var CResponse
	 */
	private $response;
	
	/**
	 * @var resource
	 */
	private $curlHandle;
	
	
	/**
	 * @var CUri
	 */
	private $URI;	
	
	/**
	 * @var integer
	 */
	private $methodType;
	
	private $userAgent;

	/**
	 * @return void 
	 */
	protected function __construct($reqURI, $methodType, $userAgent)
	{
		$this->URI = $reqURI;
		$this->methodType = $methodType;
		$this->userAgent = $userAgent;
	}
	
	/**
	 * @return CRequest
	 */
	static function getCurrent()
	{
		static $current = null;
		if (isset($current))
			return $current;

		$app = self::getApplication();
		$current = new static($app->getRequestURI(), $app->getRequestType(),
			$_SERVER['HTTP_USER_AGENT']);
		$current->response = new CResponse;
		
		return $current;
	}
	
	/**
	 * @return CUri
	 */
	function getURI()
	{
		return $this->URI;
	}
	
	/**
	 * @access protected
	 * @return void
	 */
	protected function setHeaderField($field, $value)
	{
		curl_setopt($this->curlHandle, CURLOPT_HTTPHEADER,
			[ ($field . ' :' . $value) ]);
	}	
	
	/**
	 * @access protected
	 * @return string
	 */
	protected function make($reqToken)
	{
		curl_setopt($this->curlHandle, CURLOPT_CUSTOMREQUEST, $reqToken);
		curl_setopt($this->curlHandle, CURLOPT_URL, $this->toString());
		$result = curl_exec($this->curlHandle);
		if ($result === false) {
			throw new \Exception('curl error');
		}
		
		// Split response onto its header and body.
		list($header, $body) = explode("\r\n\r\n", $result);
		
		$this->response = CResponse::createFromHeader($header);
		return $body;
	}
	
	/**
	 * @return CResponse
	 */
	final function getResponse()
	{
		return $this->response;
	}
	
	/**
	 * Returns HTTP response status code
	 * 
	 * @final
	 * @access public
	 * @return integer
	 */
	final function getStatusCode()
	{
		return $this->getResponse()->getStatusCode();
	}
	
	/**
	 * @return string
	 */
	final function getUserAgent()
	{
		return $this->userAgent;
	}
    
	/**
	 * Returns type of OS of the agent making request
	 * 
	 * @final
	 * @access public
	 * @return integer
	 */
	function getOperatingSystem()
	{
		static $OSType = null;
		
		if ($OSType !== null)
			return $OSType;
		
		$ua = $this->getUserAgent();
		if (preg_match('#Win(NT|dows)#i', $ua))
			$OSType = OS_WINDOWS;
		elseif (preg_match('#Linux#i', $ua))
			$OSType = OS_LINUX;
		elseif (preg_match('#Mac(\s|OS)#i', $ua))
			$OSType = OS_MAC;
		else
			$OSType = OS_UNKNOWN;
		
		return $OSType;
	}
	
	/**
	 * Returns request type.
	 * 
	 * Legend: 
	 *		B = Browser 
	 *		C = Link-, bookmark-, server- checking D = Downloading tool
	 *		P = Proxy server, web filtering
	 *		R = Robot, crawler, spider 
	 *		S = Spam or bad bot
	 * 
	 * @access public
	 * @return integer
	 */
	function getType()
	{
		static $ReqType = null;
		
		if ($ReqType != null)
			return $ReqType;
		
		$browserType = $this->getBrowser();
		if ($browserType != REQUEST_BROWSER_UNKNOWN)
			$ReqType = REQUEST_TYPE_BROWSER;
		
		return $ReqType;
	}
	
	/**
	 * @return integer
	 */
	final function getMethodType()
	{
		return $this->methodType;
	}
	
	/**
	 * 
	 */
	final function getBrowser()
	{
		
	}
	
	/**
	 * @return void
	 */
	function setAuthField($value)
	{
		$this->setHeaderField(REQFIELD_AUTHORIZATION, $value);
	}
	
	/**
	 * @return void
	 */
	function setHostField($hostname)
	{
		$this->setHeaderField(REQFIELD_HOST, $hostname);
	}

	/**
	 * 
	 */
	function makeGet()
	{
		return $this->make(GET);
	}
	
	/**
	 * @return string|null
	 */
	final function getCookie($name)
	{
		return isset($_COOKIE[$name]) ? $_COOKIE[$name] : null;
	}
}